#include <iostream>
#include "WaterSort.h"
#include "raylib.h"
#define RAYGUI_IMPLEMENTATION
#include "raygui.h"
State state;
const int screenWidth  = 2000;
const int screenHeight = 1000;
double MAX_X = 10;
double MAX_Y = 10;
inline float RCX(double x){
    return x * MAX_X/screenWidth;
}
inline float RCY(double y){
    return (screenHeight - y) *MAX_Y/screenHeight;
}
inline float CX(double x){
    return x * screenWidth/MAX_X;
}
inline float CY(double y){
    return screenHeight - y * screenHeight/MAX_Y;
}
inline float CDX(double dx){
    return dx * screenWidth/MAX_X;
}
inline float CDY(double dy){
    return dy * screenHeight/MAX_Y;
}
void setMaxXY()
{
    MAX_X = state.cup_num+2;
}
Color colors[] = {
    {255,0,0,255},
    {0,255,0,255},
    {0,0,255,255},
    {255,255,0,255},
    {255,0,255,255},
    {0,255,255,255},
    {128,128,128,255},
    {128,0,0,255},
    {0,128,0,255},
    {0,0,128,255},
    {128,128,0,255},
    {128,0,128,255},
    {0,128,128,255},
    {192,192,192,255},
    {192,0,0,255},
    {0,192,0,255},
    {0,0,192,255},
    {192,192,0,255},
    {192,0,192,255},
    {0,192,192,255},
    {255,0,0,255},
};
int SelectState = 0; //0:no, 1:one
int SelectIdx1 = -1;
int SelectIdx2 = -1;
char StatusString[100];
void DisplayWater()
{
    double dx = 0.35;
    double dy = 0;
    double ddx = 0.05;
    double ddy = 0.1;
    for(int i = 0; i < state.cup_num; i++){
        if(SelectIdx1 == i && SelectState == 1){
            dy = 1;
        }else{
            dy = 0;
        }
        double x1 = (i+1)-dx;
        double y1 = 8+dy;
        double x2 = x1;
        double y2 = 2+dy;
        double x3 = x1+dx*2;
        double y3 = y2;
        double x4 = x3;
        double y4 = y1;
        DrawLine(CX(x1),CY(y1),CX(x2),CY(y2),BLACK);
        DrawLine(CX(x2),CY(y2),CX(x3),CY(y3),BLACK);
        DrawLine(CX(x3),CY(y3),CX(x4),CY(y4),BLACK);
        DrawText(std::to_string(i).c_str(), CX(i+1), CY(9), 20, GRAY);
        if(state.water[i].size() > 0){
            for(int j = 0; j < state.water[i].size(); j++){
                double x = x1+ddx;
                double y = y2 +1.5 + j*1.5;
                Color color = colors[state.water[i][j]];
                DrawRectangle(CX(x), CY(y), CDX((dx-ddx)*2), CDY(1.5-ddy), color);
            }
        }
    }
}
void MouseButtonPress()
{
    if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
    {
        // 获取鼠标当前位置
        Vector2 mousePosition = GetMousePosition();
        // 输出鼠标点击位置
        double sx = RCX(mousePosition.x);
        double sy = RCY(mousePosition.y);
        int sel_idx = -1;
        for(int i = 0; i < state.cup_num; i++){
            if(sx - (i+1) < 0.35 && sx - (i+1) > -0.35 && sy > 2 && sy < 8){
                sel_idx = i;
                break;
            }
        }
        if(sel_idx != -1){
            if(SelectState == 0){
                SelectState = 1;
                SelectIdx1  = sel_idx;
                TraceLog(LOG_INFO, "SelectCup[%d]\n", SelectIdx1);
                sprintf(StatusString, "SelectCup[%d]", SelectIdx1);
            }else{
                SelectIdx2  = sel_idx;
                if(isAction(SelectIdx1, SelectIdx2, state))
                {
                    state = move({SelectIdx1, SelectIdx2}, state);
                    TraceLog(LOG_INFO, "Pour water into Cup[%d] OK\n", SelectIdx2);
                    sprintf(StatusString, "Pour water into Cup[%d] OK", SelectIdx2);
                }else{
                    TraceLog(LOG_INFO, "Pour water into Cup[%d] Not OK\n", SelectIdx2);
                    sprintf(StatusString, "Pour water into Cup[%d] Not OK", SelectIdx2);
                }
                SelectState = 0;
                SelectIdx1 = -1;
                SelectIdx2 = -1;
            }
        }else{
            if(SelectState == 1){
                SelectState = 0;
                TraceLog(LOG_INFO, "Cancel SelectCup[%d]\n", SelectIdx1);
                sprintf(StatusString, "Cancel SelectCup[%d]\n", SelectIdx1);
                SelectIdx1 = -1;
                SelectIdx2 = -1;
            }
        }
    }
}
char HinsString[500];


void DisplayUI()
{
    DrawRectangle(screenWidth-20,0,320,screenHeight,GRAY);
    DrawText(StatusString, screenWidth-20, 0, 20, BLACK);
    DrawText(HinsString, screenWidth-20, 100, 20, BLACK);
    if (GuiButton((Rectangle){ screenWidth-20, 50, 100, 50 }, "Solve"))
    {
        std::vector<std::array<int,2>> result;
        if(astar(state, result))
        {
            char *p = HinsString;
            p += sprintf(p, "Success, %d steps\n",result.size());
            for(int i = 0; i < result.size(); i++){
                if((i+1)%3==0)
                {
                    p += sprintf(p, "%d->%d\n", result[i][0], result[i][1]);
                }else{
                    p += sprintf(p, "%d->%d ", result[i][0], result[i][1]);
                }
            }
        }else{
            sprintf(HinsString, "Solve failed");
        }
    }
}
void DisplayWindow()
{
    InitWindow(screenWidth+300, screenHeight, "水排序");
    SetTargetFPS(60);
    while (!WindowShouldClose())
    {
        BeginDrawing();
        ClearBackground(RAYWHITE);
        setMaxXY();
        DisplayWater();
        DisplayUI();
        MouseButtonPress();
        EndDrawing();
    }
    CloseWindow();
}
int read_file(const char* filename, char* buffer) {
    FILE* file = fopen(filename, "rb");
    if (file == NULL) {
        perror("无法打开文件");
        return 0;
    }
    // 获取文件大小
    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    fseek(file, 0, SEEK_SET);
    // 读取文件内容
    size_t bytes_read = fread(buffer, 1, file_size, file);
    // 关闭文件
    fclose(file);
    return bytes_read;
}
int main() {
    char data[1000];
    int len = read_file("../test1.txt", data);
    std::string s;
    s.assign(data, data+len);
//    state = loadStateFromString(s);
    //state = generateRandomState(8,2, 50);
    //state = generateRandomState(12,2, 80);
    state = generateRandomState(14,2, 100);
    DisplayWindow();
    return 0;
}


